const fs = require('fs-extra');
const path = require('path');
const configLoader = require('../utils/config-loader');
const logger = require('../utils/logger');

class FileManager {
    constructor() {
        this.config = null;
    }

    async initializeStorage() {
        try {
            this.config = await configLoader.load();
            
            this.basePath = this.config.storage.basePath;
            this.storagePaths = {
                images: path.join(this.basePath, this.config.storage.images),
                voices: path.join(this.basePath, this.config.storage.voices),
                videos: path.join(this.basePath, this.config.storage.videos),
                files: path.join(this.basePath, this.config.storage.files),
                texts: path.join(this.basePath, this.config.storage.texts)
            };
            
            // 创建所有存储目录 
            for (const [type, dirPath] of Object.entries(this.storagePaths)) {
                await fs.ensureDir(dirPath);
                logger.debug(`存储目录已创建: ${dirPath}`);
            }
            
            // 创建 README 文件说明目录结构
            const readmeContent = `# 数据存储目录说明

## 目录结构
- images/    - 图片文件存储
- voices/    - 语音文件存储  
- videos/    - 视频文件存储
- files/     - 其他文件存储
- texts/     - 文本内容存储

## 文件命名规则
文件按照类型和时间戳自动分类存储
生成时间: ${new Date().toISOString()}
`;
            await fs.writeFile(path.join(this.basePath, 'README.md'), readmeContent);
            
            logger.info('存储系统初始化完成');
            return true;
        } catch (error) {
            logger.error('存储系统初始化失败:', error);
            throw error;
        }
    }

    // 保存图片文件
    async saveImage(buffer, filename = null) {
        return this.saveFile('images', buffer, filename, 'image');
    }

    // 保存语音文件
    async saveVoice(buffer, filename = null) {
        return this.saveFile('voices', buffer, filename, 'voice');
    }

    // 保存视频文件
    async saveVideo(buffer, filename = null) {
        return this.saveFile('videos', buffer, filename, 'video');
    }

    // 保存文本文件
    async saveText(content, filename = null) {
        const buffer = Buffer.from(content, 'utf8');
        return this.saveFile('texts', buffer, filename, 'text');
    }

    // 通用文件保存方法 
    async saveFile(type, buffer, filename = null, fileType = 'file') {
        try {
            if (!this.config) {
                await this.initializeStorage();
            }
            
            if (!this.storagePaths[type]) {
                throw new Error(`不支持的存储类型: ${type}`);
            }

            // 生成文件名
            const timestamp = Date.now();
            const randomStr = Math.random().toString(36).substring(2, 8);
            const extension = this.getFileExtension(buffer, fileType);
            
            const finalFilename = filename || `${timestamp}_${randomStr}${extension}`;
            const filePath = path.join(this.storagePaths[type], finalFilename);

            // 保存文件
            await fs.writeFile(filePath, buffer);
            
            const fileInfo = {
                filename: finalFilename,
                path: filePath,
                relativePath: path.relative(this.basePath, filePath),
                size: buffer.length,
                type: type,
                timestamp: timestamp,
                url: `/files/${type}/${finalFilename}`
            };

            logger.info(`文件保存成功: ${filePath} (${buffer.length} bytes)`);
            return fileInfo;

        } catch (error) {
            logger.error(`保存文件失败 [${type}]:`, error);
            throw error;
        }
    }

    // 根据文件内容和类型获取扩展名 
    getFileExtension(buffer, fileType) {
        if (buffer.length < 4) return '.bin';

        const signatures = {
            'image': {
                'ffd8ffe0': '.jpg',
                '89504e47': '.png',
                '47494638': '.gif',
                '52494646': '.webp'
            },
            'audio': {
                '494433': '.mp3',
                '52494646': '.wav'
            },
            'video': {
                '00000018': '.mp4',
                '52494646': '.avi'
            }
        };

        const hex = buffer.slice(0, 8).toString('hex').toLowerCase();
        
        if (signatures[fileType]) {
            for (const [signature, ext] of Object.entries(signatures[fileType])) {
                if (hex.startsWith(signature)) {
                    return ext;
                }
            }
        }

        // 默认扩展名
        const defaultExts = {
            'image': '.jpg',
            'voice': '.mp3',
            'video': '.mp4',
            'text': '.txt',
            'file': '.bin'
        };

        return defaultExts[fileType] || '.bin';
    }

    // 读取文件 
    async readFile(type, filename) {
        try {
            if (!this.config) {
                await this.initializeStorage();
            }
            
            const filePath = path.join(this.storagePaths[type], filename);
            if (!await fs.pathExists(filePath)) {
                throw new Error(`文件不存在: ${filePath}`);
            }
            
            return await fs.readFile(filePath);
        } catch (error) {
            logger.error(`读取文件失败 [${type}/${filename}]:`, error);
            throw error;
        }
    }

    // 获取存储统计信息
    async getStorageStats() {
        try {
            if (!this.config) {
                await this.initializeStorage();
            }
            
            const stats = {
                totalFiles: 0,
                totalSize: 0,
                byType: {}
            };

            for (const type of Object.keys(this.storagePaths)) {
                const files = await this.listFiles(type, { withStats: true });
                stats.byType[type] = {
                    count: files.length,
                    size: files.reduce((sum, file) => sum + file.size, 0)
                };
                stats.totalFiles += files.length;
                stats.totalSize += stats.byType[type].size;
            }

            return stats;
        } catch (error) {
            logger.error('获取存储统计失败:', error);
            throw error;
        }
    }

    // 列出目录下的所有文件 
    async listFiles(type, options = {}) {
        try {
            if (!this.config) {
                await this.initializeStorage();
            }
            
            const dirPath = this.storagePaths[type];
            if (!await fs.pathExists(dirPath)) {
                return [];
            }

            let files = await fs.readdir(dirPath);
            
            // 过滤隐藏文件
            files = files.filter(file => !file.startsWith('.'));
            
            // 如果需要详细信息
            if (options.withStats) {
                const filesWithStats = [];
                for (const file of files) {
                    try {
                        const filePath = path.join(dirPath, file);
                        const stats = await fs.stat(filePath);
                        filesWithStats.push({
                            name: file,
                            path: filePath,
                            size: stats.size,
                            created: stats.birthtime,
                            modified: stats.mtime,
                            isDirectory: stats.isDirectory()
                        });
                    } catch (error) {
                        logger.warn(`无法获取文件状态: ${file}`, error);
                    }
                }
                return filesWithStats;
            }
            
            return files;
        } catch (error) {
            logger.error(`列出文件失败 [${type}]:`, error);
            throw error;
        }
    }
}

module.exports = new FileManager();